/*****************************************************************************
 * Copyright (c) 2007 Rowley Associates Limited.                             *
 *                                                                           *
 * This file may be distributed under the terms of the License Agreement     *
 * provided with this software.                                              *
 *                                                                           *
 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE   *
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
 *****************************************************************************/

/*****************************************************************************
 *                           Preprocessor Definitions
 *                           ------------------------
 *
 * STARTUP_FROM_RESET
 *
 *   If defined, the program will startup from power-on/reset. If not defined
 *   the program will just loop endlessly from power-on/reset.
 *
 *   This definition is not defined by default on this target because the
 *   debugger is unable to reset this target and maintain control of it over the
 *   JTAG interface. The advantage of doing this is that it allows the debugger
 *   to reset the CPU and run programs from a known reset CPU state on each run.
 *   It also acts as a safety net if you accidently download a program in FLASH
 *   that crashes and prevents the debugger from taking control over JTAG
 *   rendering the target unusable over JTAG. The obvious disadvantage of doing
 *   this is that your application will not startup without the debugger.
 *
 *   We advise that on this target you keep STARTUP_FROM_RESET undefined whilst
 *   you are developing and only define STARTUP_FROM_RESET when development is
 *   complete.
 *
 *****************************************************************************/

  .global reset_handler

  .section .vectors, "ax"
  .code 16
  .align 0
  .global _vectors

.macro DEFAULT_ISR_HANDLER name=
  .thumb_func
  .weak \name
\name:
1: b 1b /* endless loop */
.endm

/* Interupt handlers used in the demo */
.extern xPortPendSVHandler
.extern xPortSysTickHandler
.extern vPortSVCHandler
.extern vMAC_ISR;
.extern vButtonISR;

_vectors:
  .word __stack_end__
  .word reset_handler
  .word NMI_Handler
  .word MemManage_Handler
  .word HardFault_Handler
  .word BusFault_Handler
  .word UsageFault_Handler
  .word 0 						   /* Reserved */
  .word 0 						   /* Reserved */
  .word 0 						   /* Reserved */
  .word 0 						   /* Reserved */
  .word vPortSVCHandler
  .word DebugMonitor_Handler
  .word 0 						   /* Reserved */
  .word xPortPendSVHandler
  .word xPortSysTickHandler
  .word WWDG_IRQHandler            /* Window Watchdog */
  .word PVD_IRQHandler             /* PVD through EXTI Line detect */
  .word TAMPER_IRQHandler          /* Tamper */
  .word RTC_IRQHandler             /* RTC */
  .word FLASH_IRQHandler           /* Flash */
  .word RCC_IRQHandler             /* RCC */
  .word vButtonISR           	   /* EXTI Line 0 */
  .word EXTI1_IRQHandler           /* EXTI Line 1 */
  .word EXTI2_IRQHandler           /* EXTI Line 2 */
  .word EXTI3_IRQHandler           /* EXTI Line 3 */
  .word EXTI4_IRQHandler           /* EXTI Line 4 */
  .word DMA1_Channel1_IRQHandler   /* DMA1 Channel 1 */
  .word DMA1_Channel2_IRQHandler   /* DMA1 Channel 2 */
  .word DMA1_Channel3_IRQHandler   /* DMA1 Channel 3 */
  .word DMA1_Channel4_IRQHandler   /* DMA1 Channel 4 */
  .word DMA1_Channel5_IRQHandler   /* DMA1 Channel 5 */
  .word DMA1_Channel6_IRQHandler   /* DMA1 Channel 6 */
  .word DMA1_Channel7_IRQHandler   /* DMA1 Channel 7 */
  .word ADC1_2_IRQHandler          /* ADC1 and ADC2 */
  .word CAN1_TX_IRQHandler         /* CAN1 TX */
  .word CAN1_RX0_IRQHandler        /* CAN1 RX0 */
  .word CAN1_RX1_IRQHandler        /* CAN1 RX1 */
  .word CAN1_SCE_IRQHandler        /* CAN1 SCE */
  .word EXTI9_5_IRQHandler         /* EXTI Line 9..5 */
  .word TIM1_BRK_IRQHandler        /* TIM1 Break */
  .word TIM1_UP_IRQHandler         /* TIM1 Update */
  .word TIM1_TRG_COM_IRQHandler    /* TIM1 Trigger and Commutation */
  .word TIM1_CC_IRQHandler         /* TIM1 Capture Compare */
  .word TIM2_IRQHandler            /* TIM2 */
  .word TIM3_IRQHandler            /* TIM3 */
  .word TIM4_IRQHandler            /* TIM4 */
  .word I2C1_EV_IRQHandler         /* I2C1 Event */
  .word I2C1_ER_IRQHandler         /* I2C1 Error */
  .word I2C2_EV_IRQHandler         /* I2C2 Event */
  .word I2C2_ER_IRQHandler         /* I2C1 Error */
  .word SPI1_IRQHandler            /* SPI1 */
  .word SPI2_IRQHandler            /* SPI2 */
  .word USART1_IRQHandler          /* USART1 */
  .word USART2_IRQHandler          /* USART2 */
  .word USART3_IRQHandler          /* USART3 */
  .word vButtonISR			       /* EXTI Line 15..10 */
  .word RTCAlarm_IRQHandler        /* RTC alarm through EXTI line */
  .word OTG_FS_WKUP_IRQHandler     /* USB OTG FS Wakeup through EXTI line */
  .word 0                          /* Reserved */
  .word 0                          /* Reserved */
  .word 0                          /* Reserved */
  .word 0                          /* Reserved */
  .word 0                          /* Reserved */
  .word 0                          /* Reserved */
  .word 0                          /* Reserved */
  .word TIM5_IRQHandler            /* TIM5 */
  .word SPI3_IRQHandler            /* SPI3 */
  .word UART4_IRQHandler           /* UART4 */
  .word UART5_IRQHandler           /* UART5 */
  .word TIM6_IRQHandler            /* TIM6 */
  .word TIM7_IRQHandler            /* TIM7 */
  .word DMA2_Channel1_IRQHandler   /* DMA2 Channel1 */
  .word DMA2_Channel2_IRQHandler   /* DMA2 Channel2 */
  .word DMA2_Channel3_IRQHandler   /* DMA2 Channel3 */
  .word DMA2_Channel4_IRQHandler   /* DMA2 Channel4 */
  .word DMA2_Channel5_IRQHandler   /* DMA2 Channel5 */
  .word vMAC_ISR	               /* Ethernet */
  .word vMAC_ISR		           /* Ethernet Wakeup through EXTI line */

  .section .init, "ax"
  .thumb_func

  reset_handler:
#ifndef __FLASH_BUILD
  /* If this is a RAM build, configure vector table offset register to point
     to the RAM vector table. */
  ldr r0, =0xE000ED08
  ldr r1, =_vectors
  str r1, [r0]
#endif
  b _start

DEFAULT_ISR_HANDLER HardFaultException
DEFAULT_ISR_HANDLER NMIException
DEFAULT_ISR_HANDLER MemManageException
DEFAULT_ISR_HANDLER BusFaultException
DEFAULT_ISR_HANDLER UsageFaultException
DEFAULT_ISR_HANDLER SVCHandler
DEFAULT_ISR_HANDLER DebugMonitor
DEFAULT_ISR_HANDLER PendSV
DEFAULT_ISR_HANDLER SysTickHandler
DEFAULT_ISR_HANDLER WWDG_IRQHandler
DEFAULT_ISR_HANDLER PVD_IRQHandler
DEFAULT_ISR_HANDLER TAMPER_IRQHandler
DEFAULT_ISR_HANDLER RTC_IRQHandler
DEFAULT_ISR_HANDLER FLASH_IRQHandler
DEFAULT_ISR_HANDLER RCC_IRQHandler
DEFAULT_ISR_HANDLER EXTI0_IRQHandler
DEFAULT_ISR_HANDLER EXTI1_IRQHandler
DEFAULT_ISR_HANDLER EXTI2_IRQHandler
DEFAULT_ISR_HANDLER EXTI3_IRQHandler
DEFAULT_ISR_HANDLER EXTI4_IRQHandler
DEFAULT_ISR_HANDLER DMA1_Channel1_IRQHandler
DEFAULT_ISR_HANDLER DMA1_Channel2_IRQHandler
DEFAULT_ISR_HANDLER DMA1_Channel3_IRQHandler
DEFAULT_ISR_HANDLER DMA1_Channel4_IRQHandler
DEFAULT_ISR_HANDLER DMA1_Channel5_IRQHandler
DEFAULT_ISR_HANDLER DMA1_Channel6_IRQHandler
DEFAULT_ISR_HANDLER DMA1_Channel7_IRQHandler
DEFAULT_ISR_HANDLER ADC1_2_IRQHandler
DEFAULT_ISR_HANDLER CAN1_TX_IRQHandler
DEFAULT_ISR_HANDLER CAN1_RX0_IRQHandler
DEFAULT_ISR_HANDLER CAN1_RX1_IRQHandler
DEFAULT_ISR_HANDLER CAN1_SCE_IRQHandler
DEFAULT_ISR_HANDLER EXTI9_5_IRQHandler
DEFAULT_ISR_HANDLER TIM1_BRK_IRQHandler
DEFAULT_ISR_HANDLER TIM1_UP_IRQHandler
DEFAULT_ISR_HANDLER TIM1_TRG_COM_IRQHandler
DEFAULT_ISR_HANDLER TIM1_CC_IRQHandler
DEFAULT_ISR_HANDLER TIM2_IRQHandler
DEFAULT_ISR_HANDLER TIM3_IRQHandler
DEFAULT_ISR_HANDLER TIM4_IRQHandler
DEFAULT_ISR_HANDLER I2C1_EV_IRQHandler
DEFAULT_ISR_HANDLER I2C1_ER_IRQHandler
DEFAULT_ISR_HANDLER I2C2_EV_IRQHandler
DEFAULT_ISR_HANDLER I2C2_ER_IRQHandler
DEFAULT_ISR_HANDLER SPI1_IRQHandler
DEFAULT_ISR_HANDLER SPI2_IRQHandler
DEFAULT_ISR_HANDLER USART1_IRQHandler
DEFAULT_ISR_HANDLER USART2_IRQHandler
DEFAULT_ISR_HANDLER USART3_IRQHandler
DEFAULT_ISR_HANDLER EXTI15_10_IRQHandler
DEFAULT_ISR_HANDLER RTCAlarm_IRQHandler
DEFAULT_ISR_HANDLER OTG_FS_WKUP_IRQHandler
DEFAULT_ISR_HANDLER USBWakeUp_IRQHandler
DEFAULT_ISR_HANDLER TIM8_BRK_IRQHandler
DEFAULT_ISR_HANDLER TIM8_UP_IRQHandler
DEFAULT_ISR_HANDLER TIM8_TRG_COM_IRQHandler
DEFAULT_ISR_HANDLER TIM8_CC_IRQHandler
DEFAULT_ISR_HANDLER ADC3_IRQHandler
DEFAULT_ISR_HANDLER FSMC_IRQHandler
DEFAULT_ISR_HANDLER SDIO_IRQHandler
DEFAULT_ISR_HANDLER TIM5_IRQHandler
DEFAULT_ISR_HANDLER SPI3_IRQHandler
DEFAULT_ISR_HANDLER UART4_IRQHandler
DEFAULT_ISR_HANDLER UART5_IRQHandler
DEFAULT_ISR_HANDLER TIM6_IRQHandler
DEFAULT_ISR_HANDLER TIM7_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel1_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel2_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel3_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel4_IRQHandler
DEFAULT_ISR_HANDLER DMA2_Channel5_IRQHandler

  /* STM32 library requires these */
  .global __WFI
  .global __WFE
  .global __SEV
  .global __ISB
  .global __DSB
  .global __DMB
  .global __SVC
  .global __MRS_CONTROL
  .global __MSR_CONTROL
  .global __MRS_PSP
  .global __MSR_PSP
  .global __MRS_MSP
  .global __MSR_MSP
  .global __SETPRIMASK
  .global __RESETPRIMASK
  .global __SETFAULTMASK
  .global __RESETFAULTMASK
  .global __BASEPRICONFIG
  .global __GetBASEPRI
  .global __REV_HalfWord
  .global __REV_Word

.thumb_func
__WFI:
  wfi
  bx r14
.thumb_func
__WFE:
  wfe
  bx r14
.thumb_func
__SEV:
  sev
  bx r14
.thumb_func
__ISB:
  isb
  bx r14
.thumb_func
__DSB:
  dsb
  bx r14
.thumb_func
__DMB:
  dmb
  bx r14
.thumb_func
__SVC:
  svc 0x01
  bx r14
.thumb_func
__MRS_CONTROL:
  mrs r0, control
  bx r14
.thumb_func
__MSR_CONTROL:
  msr control, r0
  isb
  bx r14
.thumb_func
__MRS_PSP:
  mrs r0, psp
  bx r14
.thumb_func
__MSR_PSP:
  msr psp, r0
  bx r14
.thumb_func
__MRS_MSP:
  mrs r0, msp
  bx r14
.thumb_func
__MSR_MSP:
  msr msp, r0
  bx r14
.thumb_func
__SETPRIMASK:
  cpsid i
  bx r14
.thumb_func
__RESETPRIMASK:
  cpsie i
  bx r14
.thumb_func
__SETFAULTMASK:
  cpsid f
  bx r14
.thumb_func
__RESETFAULTMASK:
  cpsie f
  bx r14
.thumb_func
__BASEPRICONFIG:
  msr basepri, r0
  bx r14
.thumb_func
__GetBASEPRI:
  mrs r0, basepri_max
  bx r14
.thumb_func
__REV_HalfWord:
  rev16 r0, r0
  bx r14
.thumb_func
__REV_Word:
  rev r0, r0
  bx r14
